﻿using System;

namespace CSharpConsoleTestSolution.Demo {
    /**
     * P28: 抽象类与开闭原则
     * 什么是接口和抽象类
     *  ·接口和抽象类都是“软件工程产物”
     *  ·具体类 -> 抽象类 -> 接口: 越来越抽象，内部实现的东西越来越少
     *  ·抽象类是未完全实现逻辑的类 (可以有字段和非public成员，它们代表了“具体逻辑”)
     *  ·抽象类为复用而生: 专门作为甚类来使用，也具有解耦功能
     *  ·封装确定的，开放不确定的，推迟到合适的子类中去实现
     *  ·接口是完全未实现逻辑的“类” (“纯虚类”; 只有函数成员; 成员全部public)
     *  ·接口为解耦而生: “高内聚，低耦合”，方便单元测试
     *  ·接口是一个“协约”，早已为工业生产所熟知(有分工必有协作，有协作必有协约)
     *  ·它们都不能实例化，只能用来声明变量、引用具体类 (concrete class)的实例
     */
    public class P28_abstract {

        public static void abstract_test() {
            Console.WriteLine("1.抽象类与开闭原则");
        }
        
        public interface IVehicle {
            void Run();
            void Fill();
            void Stop();
        }
        
        public abstract class Vehicle: IVehicle {
            public virtual void Run() { Console.WriteLine("Vehicle is running!"); }
            public void Fill() { Console.WriteLine("Fill the oil."); }
            public abstract void Stop();
        }
        
        public class Car: Vehicle {
            public override void Run() {
                Console.WriteLine("Car is running!");
            }
            public override void Stop() {
                Console.WriteLine("Car is Stopped!");
            }
        }
        
        public class Truck: Vehicle {
            public override void Run() {
                Console.WriteLine("Truck is running!");
            }
            public override void Stop() {
                Console.WriteLine("Truck is stopped!");
            }
        }
        
        public class Driver {
            private IVehicle _vehicle;
            public Driver(IVehicle vehicle) {
                _vehicle = vehicle;
            }
            public void Drive() {
                _vehicle.Run();
            }
        }
    }
}